import sys
from PySide6.QtWidgets import QApplication, QMainWindow, QVBoxLayout, QWidget, QComboBox, QPushButton
from PySide6.QtCore import QTimer, Qt
from PySide6.QtGui import QPainter
from PySide6.QtCharts import QChart, QChartView, QLineSeries, QValueAxis

import serial.tools.list_ports

class MainWindow(QMainWindow):
    def __init__(self):
        super().__init__()

        # 初始化串口
        self.serial_port = None
        self.selected_device = None

        # 创建一个组合框来显示所有可用的USB ACM设备
        self.combo_box = QComboBox()
        self.populate_combo_box()

        # 创建一个按钮来连接选定的设备
        self.connect_button = QPushButton("Connect")
        self.connect_button.clicked.connect(self.connect_to_device)

        # 创建图表
        self.chart = QChart()
        self.chart.legend().hide()
        self.chart.setTitle("USB ACM Data")

        # 创建系列
        self.series = QLineSeries()
        self.chart.addSeries(self.series)

        # 设置X轴和Y轴
        self.axis_x = QValueAxis()
        self.axis_y = QValueAxis()
        self.chart.addAxis(self.axis_x, Qt.AlignBottom)
        self.chart.addAxis(self.axis_y, Qt.AlignLeft)
        self.series.attachAxis(self.axis_x)
        self.series.attachAxis(self.axis_y)

        # 创建图表视图
        self.chart_view = QChartView(self.chart)
        self.chart_view.setRenderHint(QPainter.Antialiasing)

        # 布局设置
        layout = QVBoxLayout()
        layout.addWidget(self.combo_box)
        layout.addWidget(self.connect_button)
        layout.addWidget(self.chart_view)

        container = QWidget()
        container.setLayout(layout)
        self.setCentralWidget(container)

        # 定时器读取数据
        self.timer = QTimer(self)
        self.timer.timeout.connect(self.update_data)
        self.timer.start(10)  # 每50毫秒更新一次

        # 数据缓冲区
        self.x_values = [i for i in range(100)]
        self.y_values = [0] * 100
        self.index = 0

        self.resize(800,800)

    def populate_combo_box(self):
        # 清除旧的设备列表
        self.combo_box.clear()

        # 获取所有可用的串口设备
        ports = serial.tools.list_ports.comports()

        # 添加到组合框中
        for port in ports:
            self.combo_box.addItem(port.device, port)

    def connect_to_device(self):
        # 获取选定的设备
        selected_item = self.combo_box.currentData()
        if selected_item is not None:
            self.selected_device = selected_item.device
            self.serial_port = serial.Serial(self.selected_device, 9600, timeout=1)  # 替换为实际的端口号和波特率
            if self.serial_port.is_open:
                # 设置DTR信号
                self.serial_port.setDTR(True)
                print(f"DTR set to True on {self.selected_device}")

    def update_data(self):
        if self.serial_port and self.serial_port.is_open and self.serial_port.in_waiting:            
            data = self.serial_port.read(4)
            self.y_values[self.index] = data[1] + data[2]*256
            self.index = (self.index + 1) % len(self.y_values)

            # 更新曲线
            self.series.clear()
            for x, y in zip(self.x_values, self.y_values):
                self.series.append(x, y)

            # 调整X轴范围
            self.axis_x.setRange(min(self.x_values), max(self.x_values))
            self.axis_y.setRange(min(self.y_values), max(self.y_values))

if __name__ == '__main__':
    app = QApplication(sys.argv)
    window = MainWindow()
    window.show()
    sys.exit(app.exec())